package com.qili.core.quartz.CustomQuartz;

import cn.hutool.core.collection.CollectionUtil;
import com.qili.controller.zx.ZxEvaluationController;
import com.qili.core.utils.DictTypes;
import com.qili.entity.base.BaseDict;
import com.qili.entity.supplier.SupplierProject;
import com.qili.entity.sys.SysUser;
import com.qili.entity.zx.ZxProject;
import com.qili.entity.zx.ZxProjectEvaluation;
import com.qili.entity.zx.ZxProjectEvaluationScore;
import com.qili.service.SysUserService;
import com.qili.service.base.BaseDictService;
import com.qili.service.supplier.SupplierProjectManagerService;
import com.qili.service.zx.ZxProjectEvaluationScoreService;
import com.qili.service.zx.ZxProjectEvaluationService;
import com.qili.service.zx.ZxProjectService;
import lombok.extern.java.Log;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

;
;

/**
 * @author liuyang
 * @date 2021/3/10
 * @description
 */
@Log
public class AutoZxEvaluationJob implements Job {

    @Autowired
    private BaseDictService baseDictService;
    @Autowired
    private ZxProjectEvaluationService evaluationService;
    @Autowired
    private ZxProjectEvaluationScoreService evaluationScoreService;
    @Autowired
    private ZxProjectService supervisorProjectService;
    @Autowired
    private SysUserService userService;
    @Autowired
    private ZxEvaluationController evaluationController;
    @Autowired
    private SupplierProjectManagerService supplierProjectManagerService;

    /**
     * 自动处理30天之前完成的项目的评价
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info("××××××××××××××××××××执行自动评价任务×××××××××××××××××××××");
        BaseDict autoEvaDict = null;
        //获取默认评价参数(延迟天数,默认评价分数):
        BaseDict baseScoreDict = new BaseDict();
        baseScoreDict.setBadtTypecode(DictTypes.AUTOEVALUATION.getType());
        List<BaseDict> select = baseDictService.select(baseScoreDict);
        if(CollectionUtils.isEmpty(select) || select.get(0) == null){
            throw new RuntimeException("没有设置自动评价字典,自动任务结束!!");
        }else{
            autoEvaDict = select.get(0);
            if(StringUtils.isBlank(autoEvaDict.getBadtLevel1())){
                throw new RuntimeException("没有设置自动评价延迟时间,自动任务结束!!");
            }else if(StringUtils.isBlank(autoEvaDict.getBadtLevel2())){
                throw new RuntimeException("有设置自动评价分数,自动任务结束!!");
            }
        }

        //获取 xx 之前完成的项目列表:
        List<String> finishedProjectIdListXXDaysAgo = getFinishedProjectIdListXXDaysAgo();
        if(!CollectionUtils.isEmpty(finishedProjectIdListXXDaysAgo)){
            //遍历项目
            for(String projectId : finishedProjectIdListXXDaysAgo){
                ZxProject project = supervisorProjectService.selectByPrimaryKey(projectId);
                try {
                    autoCompleteEvaluation(project, autoEvaDict);
                }catch (Exception e){
                    log.warning("自动完成评价,对项目id为"+projectId+"的项目自动评价时报错了!!!");
                    e.printStackTrace();
                    continue;
                }
            }
        }else{
            log.info("没有需要进行自动评论的项目,自动任务结束!");
        }
    }

    /**
     * 获取xx天之前完成的项目列表
     * @return
     */
    private List<String> getFinishedProjectIdListXXDaysAgo(){
        return evaluationService.getFinishedProjectIdListXXDaysAgo();
    }

    /**
     * 完成某个项目需要完成的评论:
     * @param project
     */
    private void autoCompleteEvaluation(ZxProject project, BaseDict autoEvaDict){
        log.info("自动评价项目（"+project.getProjectName()+"）开始。。。。。。");
        //项目类型:
        String projectSource = project.getProjectSource();
        SysUser creator = null;
        //项目创建人:
        String creatorId = project.getCreateBy();
        if(StringUtils.isNotBlank(creatorId)){
            creator = userService.selectByPrimaryKey(creatorId);
        }else{
            log.warning("自动完成项目评价时,没有获取到创建人id");
            return ;
        }
        if(null == creator){
            log.warning("自动完成项目评价时,根据id"+creatorId+"没有获取到创建人");
            return ;
        }



        //评价实施人员/供方/监理项目经理的评价(该评价是任何情况下都有的评价)
        evaluationSS(project,autoEvaDict);
        //如果发布人是正中,并且项目类型是供需类型,那么需要评价市场人员:
        log.info("creator.source....:"+creator.getSource()+",,,projectSource:"+projectSource);
        if(StringUtils.isNotBlank(creator.getSource()) && StringUtils.isNotBlank(projectSource)&& "001".equals(creator.getSource()) && "002".equals(projectSource)){
            //评价市场人员/项目发布人
            evaulationSC(project,autoEvaDict);
        }

    }

    /**
     * 评价实施人员(监理项目经理)
     * @param project
     */
    private void evaluationSS(ZxProject project,BaseDict autoEvaDict){
        log.info("开始评价实施人员....");
        //监理项目经理id:
        String targetId = project.getProjectManagerPerson();
        if(StringUtils.isBlank(targetId)){
            return ;
        }
        //项目创建人:
        SysUser projectCreator = userService.selectByPrimaryKey(project.getCreateBy());
        String source = "003";
        if(StringUtils.isNotBlank(projectCreator.getSource()) && "001".equals(projectCreator.getSource())){
            source = "001";
        }
        String aIndex = "1";
        //获取该项目所有的没有对实施人员评价的人员id列表:
        List<String> notEvaSSUserIds = evaluationService.getNotEvaSSUserIds(project.getId());
        if(CollectionUtil.isNotEmpty(notEvaSSUserIds)){
            //一个个遍历评价默认分
            for(String creater : notEvaSSUserIds){
                //查询当前人员  关于当前项目 是否已经提交了评价:
                SysUser creatoor = userService.selectByPrimaryKey(creater);
                SysUser targeter = userService.selectByPrimaryKey(targetId);
                if(checkIfEvaed(creater,targetId,project.getId(),"1")){
                    log.info("项目id:"+project.getId()+",评价人:"+creatoor.getUsername()+",被评价人:"+targeter.getUsername()+",已经评价过实施人员");
                }else{
                    if(creatoor == null || targetId == null){
                        continue ;
                    }
                    log.info("评价实施人员,,当前评价人:"+creatoor.getUsername()+",被评价人:"+targeter.getUsername()+",项目id:"+project.getId()+",项目名称："+project.getProjectName());
                    ZxProjectEvaluation evaluation = new ZxProjectEvaluation();
                    evaluation.setSpId(project.getId());
                    evaluation.setScore(autoEvaDict.getBadtLevel2());
                    evaluation.setSource(source);
                    evaluation.setAindex(aIndex);
                    evaluation.setCreateBy(creater);
                    evaluation.setSpeTarget(targetId);
                    setAutoEvaScoreList(evaluation,project,autoEvaDict);
                    evaluation.setAuto("1");
                    evaluationController.insertEvaluation(evaluation);
                }
            }
        }
    }

    /**
     * 评价市场人员
     * @param project
     */
    private void evaulationSC(ZxProject project,BaseDict autoEvaDict){
        log.info("开始评价市场人员....");
        //目前供需系统没有完善,以创建人为被评价人,后期完善　　2021－04－29修改为对项目发布人的评价：
        String targetId = "";
        String supProjectId = project.getSupProjectId();
        if(StringUtils.isNotBlank(supProjectId)){
            SupplierProject supplierProject = supplierProjectManagerService.selectByPrimaryKey(project.getSupProjectId());
            if(supplierProject != null){
                targetId = supplierProject.getPublishBy();
            }
        }
        if(StringUtils.isBlank(targetId)){
            log.warning("自动评价市场人员（项目发布人）时，根据监理项目（id:"+project.getId()+"）没有获取到发布人");
            return ;
        }
        //项目创建人:
        SysUser projectCreator = userService.selectByPrimaryKey(project.getCreateBy());
        String source = "003";
        if(StringUtils.isNotBlank(projectCreator.getSource()) && "001".equals(projectCreator.getSource())){
            source = "001";
        }
        String aIndex = "2";
        //获取该项目所有的没有对市场人员评价的人员id列表:
        Map paraMap = new HashMap<String,String>();
        paraMap.put("id",project.getId());
        paraMap.put("targetId",targetId);
        List<String> notEvaSCUserIds = evaluationService.getNotEvaSCUserIds(paraMap);
        if(!CollectionUtils.isEmpty(notEvaSCUserIds)){
            //一个个遍历评价默认分
            for(String creater : notEvaSCUserIds){
                SysUser creatoor = userService.selectByPrimaryKey(creater);
                SysUser targeter = userService.selectByPrimaryKey(targetId);
                //查询当前人员  关于当前项目 是否已经提交了评价:
                if(checkIfEvaed(creater,targetId,project.getId(),"2")){
                    log.info("项目id:"+project.getId()+",评价人:"+creatoor.getUsername()+",被评价人:"+targeter.getUsername()+",已经评价过市场人员");
                }else{
                    log.info("评价市场人员,,当前评价人:"+creatoor.getUsername()+",被评价人:"+targeter.getUsername()+",项目id:"+project.getId()+",项目名称："+project.getProjectName());
                    ZxProjectEvaluation evaluation = new ZxProjectEvaluation();
                    evaluation.setSpId(project.getId());
                    evaluation.setScore(autoEvaDict.getBadtLevel2());
                    evaluation.setSource(source);
                    evaluation.setAindex(aIndex);
                    evaluation.setCreateBy(creater);
                    setAutoEvaScoreList(evaluation,project,autoEvaDict);
                    evaluationController.insertEvaluation(evaluation);
                }
            }
        }
    }

    /**
     * 设置默认评分项
     * @param evaluation
     * @param project
     */
    private void setAutoEvaScoreList(ZxProjectEvaluation evaluation,ZxProject project,BaseDict autoEvaDict){
        List<ZxProjectEvaluationScore> scoreList = new ArrayList<ZxProjectEvaluationScore>();
        List<BaseDict> evaContentList = getEvaContentList(evaluation, project);
        if(!CollectionUtils.isEmpty(evaContentList)){
            evaContentList.forEach(aDict->{
                ZxProjectEvaluationScore oneEvaScore = new ZxProjectEvaluationScore();
                oneEvaScore.setBdBadtCode(aDict.getBadtCode());
                oneEvaScore.setSpesScore(autoEvaDict.getBadtLevel2());
                scoreList.add(oneEvaScore);
            });
            if(CollectionUtils.isEmpty(scoreList)){
                log.warning("evaluation中没有设置默认评分项!");
                return ;
            }
            evaluation.setScoreList(scoreList);
        }else{
            throw new RuntimeException("自动评价时,没有获取到评价项目");
        }

    }

    private List<BaseDict> getEvaContentList(ZxProjectEvaluation evaluation,ZxProject project){
        List result = new ArrayList<BaseDict>();
        Example example = new Example(BaseDict.class);
        example.and().andEqualTo("badtTypecode",DictTypes.PJXM.getType());
        if("003".equals(evaluation.getSource())
                || ("001".equals(evaluation.getSource()) && "1".equals(evaluation.getAindex()))){
            //封装对监理项目经理的评价项目
            //查询需要对项目经理评价项目:
            example.and().andEqualTo("badtLevel1","1");

        }else if("001".equals(evaluation.getSource()) && "2".equals(evaluation.getAindex())){
            if(StringUtils.isBlank(project.getCreateBy())){
                throw new RuntimeException("自动评价时,没有找到该项目的创建人");
            }
            //封装对项目发布人(目前供需系统没有完善,这里使用的是项目的创建人,后期需要更改为项目的发布人)
            example.and().andEqualTo("badtLevel2","1");
        }
        example.orderBy("badtLevel3");
        return baseDictService.selectByExample(example);
    }

    /**
     * 判断某人对某某人,关于某项目是否进行了某种类型的评价
     * @param creater       评价人Id
     * @param targetId      被评价人Id
     * @param projectId     项目id
     * @param evaType       评价类型
     * @return              评价过,返回true,否则返回false
     */
    private boolean checkIfEvaed(String creater,String targetId,String projectId,String evaType){
        ZxProjectEvaluation evaluation = new ZxProjectEvaluation();
        evaluation.setSpId(projectId);
        evaluation.setSpeTarget(targetId);
        evaluation.setCreateBy(creater);
        evaluation.setSpeType(evaType);
        List<ZxProjectEvaluation> evalFinished = evaluationService.select(evaluation);
        return !CollectionUtils.isEmpty(evalFinished);
    }

}
